home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-02-09 | 13.9 KB | 632 lines | [TEXT/MPS ] |
- ;; Copyright 1988, Gail Zacharias. All rights reserved.
- ;; Permission is hereby granted to copy, reproduce, redistribute or
- ;; otherwise use this software provided there is no monetary profit
- ;; gained specifically from its use or reproduction, it is not sold,
- ;; rented, traded or otherwise marketed, and this copyright notice
- ;; and the software version number is included prominently in any copy
- ;; made.
- ;; This is ShoveIt version 1.0.
- ;;
- ;; Send comments, suggestions, bug reports (not bloody likely), feature
- ;; requests, etc. to gz@entity.com.
- ;;
-
- ;; Edit history:
- ;; 6/3/88 gz 1.0 released
-
- include 'sysequ.a'
- include 'toolequ.a'
- include 'packmacs.a'
- include 'syserr.a'
- include 'traps.a'
- load 'FlowCtlMacs.d'
- case object
- string pascal
-
- import (_RTInit, exit, write):code ;runtime.o
- import (compinit, compwrite, compclose):code ;compstream.a.o
-
-
- sVers equ 01
-
- readbufsize equ 512 ;(Must be at least 256...)
-
- shdrrec record 0
- sit ds.l 1 ;'SIT!'
- fcount ds.w 1 ;number of files
- length ds.l 1 ;length of archive
- sig2 ds.l 1 ;meglomania
- vers ds.b 1 ;version
- ds.b 7 ;unused
- size equ *-shdrrec
- endr
-
- fhdrrec record 0
- rcomp ds.b 1 ;rsrc fork compression method
- dcomp ds.b 1 ;data for compression method
- fname ds.b 64 ;file name, pstr.
- ftype ds.l 1 ;file type
- fcreat ds.l 1 ;file creator
- fflags ds.w 1 ;finder flags
- cdate ds.l 1 ;creation date
- mdate ds.l 1 ;modification date
- rlglen ds.l 1 ;rsrc fork length
- dlglen ds.l 1 ;data fork length
- rlen ds.l 1 ;rsrc compressed length
- dlen ds.l 1 ;data compressed length
- rcrc ds.w 1 ;rsrc fork crc
- dcrc ds.w 1 ;data fork crc
- ds.b 6 ;unused
- hcrc ds.w 1 ;header crc
- size equ *-fhdrrec
- endr
-
- ; A6 variables
- globals record -4,decr
- docomp ds.w 1 ;This was gonna be a user option but I can't get Stuffit
- ;to extract uncompressed entries!!!
- fname ds.l 1
- sitname ds.l 1
- sitvrefnum ds.w 1
- pgmname ds.l 1
- shdr ds.b shdrrec
- fhdr ds.b fhdrrec
- ipb ds.b ioHVQElSize
- opb ds.b ioHVQElSize
- readbuf ds.b readbufsize
- fprecsz equ *
- endr
-
- ShoveIt main
- subq #8,sp
- pea 1 ;forPascal = true
- pea 0 ;pEnvP
- pea 12(sp) ;pArgV
- pea 12(sp) ;pArgC
- pea @exit ;retPC
- jsr _RTInit
- lea 20(sp),sp
- move.l (sp)+,d0
- move.l (sp)+,a0
- bsr.s shovethem
- move.l d0,-(sp)
- jsr exit
- addq #4,sp
- @exit rts
-
- with globals
-
- shovethem
- argv set a3
- argc set d3
- movem.l d2-d7/a2-a4,-(sp)
- link a6,#fprecsz
- move.l a0,argv
- move.l d0,argc
- clr.w ipb+ioRefnum(a6)
- clr.w opb+ioRefnum(a6)
- move.w #1,docomp(a6)
- move.l (argv)+,pgmname(a6)
- subq.l #2,argc
- ble.s @usage
- move.l (argv)+,a0 ;Output filename
- moveq #0,d0
- bsr openoutput
- lea shdr(a6),a0
- moveq #shdrrec.size,d0
- bsr clearbuf
- lea shdr(a6),a1
- moveq #shdrrec.size,d1
- add.l d1,shdr.length(a6)
- bsr shovebuf
- repeat#
- move.l (argv)+,a0
- moveq #0,d0
- bsr shovefile
- addq.w #1,shdr.fcount(a6)
- subq.l #1,argc
- until#.s eq
- move.l #'SIT!',shdr.sit(a6)
- move.l #'rLau',shdr.sig2(a6)
- move.b #sVers,shdr.vers(a6)
- lea shdr(a6),a1
- moveq #shdrrec.size,d1
- moveq #0,d0
- bsr stuffit
- bsr closeoutput
- moveq #0,d0
- bra.s return
-
- @usage lea #'Usage: ',a0
- bsr errout
- move.l pgmname(a6),a0
- bsr errout
- lea #' output-file input-files...',a0
- bsr errout
- lea cr(pc),a0
- bsr errout
- moveq #2,d0
- return: move.l d0,-(sp)
- tst.w ipb+ioRefNum(a6)
- if# ne then.s
- lea ipb(a6),a0
- _Close
- endif#
- tst.w opb+ioRefNum(a6)
- if# ne then.s
- lea opb(a6),a0
- _Close
- move.l sitname(a6),opb+ioFileName(a6)
- move.w sitvrefnum(a6),opb+ioVRefNum(a6)
- sf opb+ioFileType(a6)
- lea opb(a6),a0
- _Delete
- endif#
- move.l (sp)+,d0
- unlk a6
- movem.l (sp)+,d2-d7/a2-a4
- rts
-
-
- ;A0=filename, D0=vrefnum.
- shovefile:
- vrefnum set d7
- startp set d6
- movem.l vrefnum/startp,-(sp)
- move.l shdr.length(a6),startp
- move.w d0,vrefnum
- move.l a0,fname(a6)
- move.l a0,a1
- move.w d0,d1
- lea ipb(a6),a0
- bsr GetFileInfo
- bne read_err
- lea fhdr(a6),a0
- moveq #fhdrrec.size,d0
- bsr clearbuf
- move.w #$0202,fhdr.rcomp(a6)
- move.l ipb+ioFlUsrWds+fdType(a6),fhdr.ftype(a6)
- move.l ipb+ioFlUsrWds+fdCreator(a6),fhdr.fcreat(a6)
- move.w ipb+ioFlUsrWds+fdFlags(a6),fhdr.fflags(a6)
- move.l ipb+ioFlCrDat(a6),fhdr.cdate(a6)
- move.l ipb+ioFlMdDat(a6),fhdr.mdate(a6)
- move.l ipb+ioFlLgLen(a6),fhdr.dlglen(a6)
- move.l ipb+ioFlRLgLen(a6),fhdr.rlglen(a6)
- move.l fname(a6),a0
- moveq #0,d1
- move.b (a0)+,d1
- add.w d1,a0
- moveq #0,d0
- subq #1,d1
- @loop addq #1,d0
- cmp.b #':',-(a0)
- dbeq d1,@loop
- if# eq then.s
- addq #1,a0
- subq #1,d0
- endif#
- lea fhdr.fname(a6),a1
- move.b d0,(a1)+
- _BlockMove
-
- lea fhdr(a6),a1
- moveq #fhdrrec.size,d1
- add.l d1,shdr.length(a6)
- bsr shovebuf
- move.l fname(a6),ipb+ioFileName(a6)
- move.w vrefnum,ipb+ioVRefNum(a6)
- sf ipb+ioFileType(a6)
- move.b #fsRdPerm,ipb+ioPermssn(a6)
- clr.l ipb+ioOwnBuf(a6)
- lea ipb(a6),a0
- _OpenRF
- bne read_err
- move.l fhdr.rlglen(a6),d0
- bsr shovefork
- if# eq then.s
- sf fhdr.rcomp(a6)
- endif#
- move.l d0,fhdr.rlen(a6)
- move.w d1,fhdr.rcrc(a6)
- lea ipb(a6),a0
- _Close
- clr.w ioRefNum(a0)
- move.l fname(a6),ipb+ioFileName(a6)
- move.w vrefnum,ipb+ioVRefNum(a6)
- sf ipb+ioFileType(a6)
- move.b #fsRdPerm,ipb+ioPermssn(a6)
- clr.l ipb+ioOwnBuf(a6)
- lea ipb(a6),a0
- _Open
- bne read_err
- move.l fhdr.dlglen(a6),d0
- bsr.s shovefork
- if# eq then.s
- sf fhdr.dcomp(a6)
- endif#
- move.l d0,fhdr.dlen(a6)
- move.w d1,fhdr.dcrc(a6)
- lea ipb(a6),a0
- _Close
- clr.w ioRefNum(a0)
- lea fhdr(a6),a0
- moveq #fhdrrec.size-2-1,d0
- moveq #0,d2
- @crc: move.b (a0)+,d1
- eor.b d1,d2
- move.w d2,d1
- add.w d1,d1
- lea crctab(pc),a1
- add.w d1,a1 ;two memory accesses, but it's still
- move.b (a1)+,d2 ;faster than a lsr.w #8! (Might want
- swap d2 ;to use a different strategy on a '20)
- move.b (a1),d1
- eor.b d1,d2
- dbf d0,@crc
- move.b d2,fhdr.hcrc+1(a6)
- swap d2
- move.b d2,fhdr.hcrc(a6)
- lea fhdr(a6),a1
- moveq #fhdrrec.size,d1
- move.l startp,d0
- bsr stuffit
- movem.l (sp)+,vrefnum/startp
- rts
-
- ;shove d0 bytes from ipb to opb, updating shdr.length
- ;returns number of bytes written in d0 and crc in d1.
- ;Z flag is set if not compressed.
- shovefork:
- crc set d6
- loglen set d5
- count set d4
- cstream set d3
- ctab set a4
- ptr set a3
- movem.l loglen/count/crc/cstream/ctab/ptr,-(sp)
- moveq #0,crc
- lea crctab(pc),ctab
- move.l d0,loglen
- beq @ret
- tst.w docomp(a6)
- beq @plain
- pea opb(a6) ;param
- pea @output(pc) ;outputfn
- pea 1 ;block_compress
- pea 14 ;maxbits
- jsr compinit
- lea 16(sp),sp
- move.l d0,cstream
- if# eq then.s
- lea #'Out of memory',a0
- bra fatal
- endif#
- move.l loglen,count
- lea readbuf(a6),a0
- move.l a0,ipb+ioBuffer(a6)
- move.l #readbufsize,ipb+ioByteCount(a6)
- move.w #fsAtMark,ipb+ioPosMode(a6)
- repeat#
- if# count cs.l ipb+ioByteCount(a6) then.s
- move.l count,ipb+ioByteCount(a6)
- endif#
- lea ipb(a6),a0
- _Read
- bne read_err
- move.l ipb+ioBuffer(a6),a1
- move.l ipb+ioNumDone(a6),d1
- beq read_err
- move.l a1,-(sp)
- move.l d1,-(sp)
- subq.w #1,d1
- @crc: move.b (a1)+,d0
- eor.b d0,crc
- move.w crc,d0
- add.w d0,d0
- lea 0(ctab,d0.w),a0 ;two memory accesses, but it's still
- move.b (a0)+,crc ;faster than a lsr.w #8! (Might want
- swap crc ;to use a different strategy on a '20)
- move.b (a0),d0
- eor.b d0,crc
- dbf d1,@crc
- move.l cstream,-(sp)
- jsr compwrite
- tst.w d0
- bmi write_err
- lea 12(sp),sp
- sub.l ipb+ioNumDone(a6),count
- until#.s eq
- move.l cstream,-(sp)
- jsr compclose
- addq #4,sp
- tst.w d0
- bmi write_err
- lea opb(a6),a0
- _GetFPos
- bne write_err
- move.l opb+ioPosOffset(a6),d0
- sub.l shdr.length(a6),d0
- cmp.l loglen,d0
- bcs @ret
- ;no pain, no gain.
- bsr setoutpos
- move.w #fsFromStart,ipb+ioPosMode(a6)
- clr.l ipb+ioPosOffset(a6)
- lea ipb(a6),a0
- _SetFPos
- bne read_err
- @plain move.l loglen,count
- lea readbuf(a6),a0
- move.l a0,ipb+ioBuffer(a6)
- move.l #readbufsize,ipb+ioByteCount(a6)
- move.w #fsAtMark,ipb+ioPosMode(a6)
- repeat#
- if# count cs.l ipb+ioByteCount(a6) then.s
- move.l count,ipb+ioByteCount(a6)
- endif#
- lea ipb(a6),a0
- _Read
- bne read_err
- move.l ipb+ioBuffer(a6),a1
- move.l ipb+ioNumDone(a6),d1
- beq read_err
- tst.w docomp(a6)
- if# eq then.s
- move.l a1,ptr
- move.l d1,d2
- subq.w #1,d2
- @pcrc: move.b (ptr)+,d0
- eor.b d0,crc
- move.w crc,d0
- add.w d0,d0
- lea 0(ctab,d0.w),a0 ;two memory accesses, but it's still
- move.b (a0)+,crc ;faster than a lsr.w #8! (Might want
- swap crc ;to use a different strategy on a '20)
- move.b (a0),d0
- eor.b d0,crc
- dbf d2,@pcrc
- endif#
- bsr shovebuf
- sub.l ipb+ioNumDone(a6),count
- until#.s eq
- tst.w docomp(a6)
- if# ne then.s
- move.l shdr.length(a6),opb+ioLEOF(a6)
- add.l loglen,opb+ioLEOF(a6)
- lea opb(a6),a0
- _SetEof
- bne write_err
- endif#
- move.l loglen,d0
- @ret add.l d0,shdr.length(a6)
- move.w crc,d1
- lsr.l #8,crc
- or.w crc,d1
- cmp.l loglen,d0 ;set compressed flag.
- movem.l (sp)+,loglen/count/crc/cstream/ctab/ptr
- rts
-
- @output
- move.l 4(sp),a0
- move.l 8(sp),ioByteCount(a0)
- move.l 12(sp),ioBuffer(a0)
- move.w #fsAtMark,ioPosMode(a0)
- _Write
- if# eq then.s
- move.l ioNumDone(a0),d0
- cmp.l ioByteCount(a0),d0
- beq.s @rts
- endif#
- tst.w d0
- if# pl then.s
- moveq #writErr,d0
- endif#
- ext.l d0
- @rts rts
-
- stuffit
- move.l d0,opb+ioPosOffset(a6)
- move.w #fsFromStart,opb+ioPosMode(a6)
- bsr.s writeit
- setoutpos:
- move.w #fsFromStart,opb+ioPosMode(a6)
- move.l shdr.length(a6),opb+ioPosOffset(a6)
- lea opb(a6),a0
- _SetFPos
- bne.s write_err
- rts
-
- shovebuf
- move.w #fsAtMark,opb+ioPosMode(a6)
- writeit lea opb(a6),a0
- move.l a1,ioBuffer(a0)
- move.l d1,ioByteCount(a0)
- _Write
- bne.s write_err
- rts
-
-
- read_err:
- move.w d0,d2 ;save error code
- if# eq then.s
- moveq #readErr,d2
- endif#
- lea #'Can''t read "',a0
- move.l fname(a6),a1
- bra.s xioerror
-
- write_err:
- move.w d0,d2
- if# eq then.s
- moveq #writErr,d2
- endif#
- lea #'Can''t write "',a0
- move.l sitname(a6),a1
- xioerror
- move.l a1,-(sp)
- lea readbuf(a6),a2
- sf (a2)
- bsr append
- move.l (sp)+,a0
- bsr append
- ;Check for some errors which might be meaningful to the user...
- if# d2 eq #bdNamErr then.s
- lea #'" - Bad file name',a0
- elseif#.s d2 eq #fnfErr then.s
- lea #'" - File not found',a0
- elseif#.s d2 eq #nsvErr then.s
- lea #'" - No such volume',a0
- elseif#.s d2 eq #dirNFErr then.s
- lea #'" - No such directory',a0
- elseif#.s d2 eq #tmfoErr then.s
- lea #'" - Too many files open',a0
- elseif#.s d2 eq #dupFNErr then.s
- lea #'" - File already exists',a0
- elseif#.s d2 eq #dirFulErr then.s
- lea #'" - Directory full',a0
- elseif#.s d2 eq #dskFulErr then.s
- lea #'" - Disk full',a0
- elseif#.s d2 eq #fBsyErr then.s
- lea #'" - File is in use',a0
- else#.s
- lea #'" (Error #',a0
- bsr.s append
- subq #8,sp
- move.l sp,a0
- move.b #7,(a0)
- move.w d2,d0
- ext.l d0
- _NumToString
- bsr.s append
- addq #8,sp
- lea #')',a0
- endif#
- bsr.s append
- move.l a2,a0
- fatal move.l a0,-(sp)
- move.l pgmname(a6),a0
- bsr.s errout
- lea #': ',a0
- bsr.s errout
- move.l (sp)+,a0
- bsr.s errout
- lea cr(pc),a0
- bsr.s errout
- moveq #1,d0
- bra return
-
- cr dc.b 1,13
-
- errout moveq #0,d0
- move.b (a0)+,d0
- move.l d0,-(sp)
- move.l a0,-(sp)
- pea 2
- jsr write
- lea 12(sp),sp
- rts
-
- ;Only called when we're about to exit, don't bother bounds checking...
- append: move.l a2,a1
- moveq #0,d0
- move.b (a1)+,d0
- add.w d0,a1
- move.b (a0)+,d0
- add.b d0,(a2)
- _BlockMove
- rts
-
- ;a0 = filename, d0 = vrefnum
- openoutput:
- move.l a0,sitname(a6)
- move.w d0,sitvrefnum(a6)
- move.l a0,opb+ioFileName(a6)
- move.w d0,opb+ioVRefNum(a6)
- sf opb+ioFileType(a6)
- lea opb(a6),a0
- _Create
- bne write_err
- move.b #fsWrPerm,ioPermssn(a0)
- clr.l ioOwnBuf(a0)
- _Open
- bne write_err
- rts
-
- closeoutput
- lea opb(a6),a0
- _Close
- clr.w opb+ioRefNum(a6)
- tst.w d0
- bne write_err
- move.l sitname(a6),a1
- move.w sitvrefnum(a6),d1
- lea opb(a6),a0
- bsr.s GetFileInfo
- bne write_err
- move.l sitname(a6),opb+ioFileName(a6)
- move.w sitvrefnum(a6),opb+ioVRefNum(a6)
- move.l #'SIT!',opb+ioFlUsrWds+fdType(a6)
- move.l #'SIT!',opb+ioFlUsrWds+fdCreator(a6)
- lea opb(a6),a0
- _SetFileInfo
- bne write_err
- _FlushVol
- rts
-
- ;a0=pb, a1=filename, d1=vrefnum
- GetFileInfo:
- lea 256(a1),a1
- moveq #64-1,d0
- move.l -(a1),-(sp)
- dbf d0,*-2
- move.l sp,ioFileName(a0)
- move.w d1,ioVRefNum(a0)
- sf ioFileType(a0)
- clr.w ioFDirIndex(a0)
- _GetFileInfo
- clr.w ioRefNum(a0)
- lea 256(sp),sp
- tst.w d0
- rts
-
- clearbuf:
- bra.s @1
- @0 sf (a0)+
- @1 dbf d0,@0
- rts
-
- crctab:
- dc.w $0000, $c0c1, $c181, $0140, $c301, $03c0, $0280, $c241
- dc.w $c601, $06c0, $0780, $c741, $0500, $c5c1, $c481, $0440
- dc.w $cc01, $0cc0, $0d80, $cd41, $0f00, $cfc1, $ce81, $0e40
- dc.w $0a00, $cac1, $cb81, $0b40, $c901, $09c0, $0880, $c841
- dc.w $d801, $18c0, $1980, $d941, $1b00, $dbc1, $da81, $1a40
- dc.w $1e00, $dec1, $df81, $1f40, $dd01, $1dc0, $1c80, $dc41
- dc.w $1400, $d4c1, $d581, $1540, $d701, $17c0, $1680, $d641
- dc.w $d201, $12c0, $1380, $d341, $1100, $d1c1, $d081, $1040
- dc.w $f001, $30c0, $3180, $f141, $3300, $f3c1, $f281, $3240
- dc.w $3600, $f6c1, $f781, $3740, $f501, $35c0, $3480, $f441
- dc.w $3c00, $fcc1, $fd81, $3d40, $ff01, $3fc0, $3e80, $fe41
- dc.w $fa01, $3ac0, $3b80, $fb41, $3900, $f9c1, $f881, $3840
- dc.w $2800, $e8c1, $e981, $2940, $eb01, $2bc0, $2a80, $ea41
- dc.w $ee01, $2ec0, $2f80, $ef41, $2d00, $edc1, $ec81, $2c40
- dc.w $e401, $24c0, $2580, $e541, $2700, $e7c1, $e681, $2640
- dc.w $2200, $e2c1, $e381, $2340, $e101, $21c0, $2080, $e041
- dc.w $a001, $60c0, $6180, $a141, $6300, $a3c1, $a281, $6240
- dc.w $6600, $a6c1, $a781, $6740, $a501, $65c0, $6480, $a441
- dc.w $6c00, $acc1, $ad81, $6d40, $af01, $6fc0, $6e80, $ae41
- dc.w $aa01, $6ac0, $6b80, $ab41, $6900, $a9c1, $a881, $6840
- dc.w $7800, $b8c1, $b981, $7940, $bb01, $7bc0, $7a80, $ba41
- dc.w $be01, $7ec0, $7f80, $bf41, $7d00, $bdc1, $bc81, $7c40
- dc.w $b401, $74c0, $7580, $b541, $7700, $b7c1, $b681, $7640
- dc.w $7200, $b2c1, $b381, $7340, $b101, $71c0, $7080, $b041
- dc.w $5000, $90c1, $9181, $5140, $9301, $53c0, $5280, $9241
- dc.w $9601, $56c0, $5780, $9741, $5500, $95c1, $9481, $5440
- dc.w $9c01, $5cc0, $5d80, $9d41, $5f00, $9fc1, $9e81, $5e40
- dc.w $5a00, $9ac1, $9b81, $5b40, $9901, $59c0, $5880, $9841
- dc.w $8801, $48c0, $4980, $8941, $4b00, $8bc1, $8a81, $4a40
- dc.w $4e00, $8ec1, $8f81, $4f40, $8d01, $4dc0, $4c80, $8c41
- dc.w $4400, $84c1, $8581, $4540, $8701, $47c0, $4680, $8641
- dc.w $8201, $42c0, $4380, $8341, $4100, $81c1, $8081, $4040
- END
-